/*************  技术支持与购买说明    **************
产品主页：http://tw51.haohaodada.com
淘宝搜索：天问51，可购买。目前基础版99元，带彩屏标准备版149元，旗舰版299
技术支持QQ群一：1138055784
******************************************/

#ifndef __HARDIIC_H
#define __HARDIIC_H

#include <stc16f.h>
#include "delay.h"

#define  HARDIIC_IICX           0x80        //将IIC设置为P1_5,P1_4
#define  HARDIIC_SCL_OUT      {P1M1|=0x20;P1M0|=0x20;}   //开漏输出
#define  HARDIIC_SDA_OUT      {P1M1|=0x10;P1M0|=0x10;}   //开漏输出

void hardiic_init();
void hardiic_read_nbyte(uint8 device_addr, uint8 reg_addr, uint8 *p, uint8 number);
void hardiic_write_nbyte(uint8 device_addr, uint8 reg_addr, uint8 *p, uint8 number);

//========================================================================
// 描述: 等待以及清除中断标志位.
// 参数: none.
// 返回: none.
//========================================================================
void hardiic_wait()
{
    while(!(I2CMSST &0x40));
    I2CMSST &= ~0x40;
}

//========================================================================
// 描述: IIC初始化.
// 参数: none.
// 返回: none.
//========================================================================
void hardiic_init()
{
    HARDIIC_SCL_OUT;                      //开漏输出
    HARDIIC_SDA_OUT;                      //开漏输出
    P_SW2 |= HARDIIC_IICX;                  //外设端口切换控制寄存器
    I2CCFG = 0xe0;                  //使能IIC主机模式
    I2CMSST = 0x00;                 //IIC主机状态寄存器清零
}

//========================================================================
// 描述: IIC发送start信号.
// 参数: none.
// 返回: none.
//========================================================================
void hardiic_start()
{
    I2CMSCR = 0x01;                         //发送START命令 
    hardiic_wait();
}

//========================================================================
// 描述: IIC发送stop信号.
// 参数: none.
// 返回: none.
//========================================================================
void hardiic_stop()
{
    I2CMSCR = 0x06;                         //发送stop命令
    hardiic_wait();	
}

//========================================================================
// 描述: IIC等待ack信号.
// 参数: none.
// 返回: 0，接收到应答信号; 1，没有接收到应答信号.
//========================================================================
uint8 hardiic_wait_ack()
{
    I2CMSCR = 0x03; 
    hardiic_wait();
    if( I2CMSST & 0x02){
        return 1;
    }
    return 0;
}

//========================================================================
// 描述: IIC发送ack信号.
// 参数: none.
// 返回: none.
//========================================================================
void hardiic_ack()
{
    I2CMSST = 0x00;                         //设置ACK信号
    I2CMSCR = 0x05;                         //发送ACK命令
    hardiic_wait();
}

//========================================================================
// 描述: IIC发送NAck信号.
// 参数: none.
// 返回: none.
//========================================================================
void hardiic_nack()
{
    I2CMSST = 0x01;                         //设置NAK信号
    I2CMSCR = 0x05;                         //发送ACK命令
    hardiic_wait();
}

//========================================================================
// 描述: IIC发送一个字节数据.
// 参数: 发送的字节数据.
// 返回: none.
//========================================================================
void hardiic_send_byte(uint8 iic_data)
{
    I2CTXD = iic_data;
    I2CMSCR = 0x02; 
	hardiic_wait();
}	

//========================================================================
// 描述: IIC读取一个字节数据.
// 参数: none
// 返回: 读取到的字节数据.
//========================================================================
uint8 hardiic_read_byte()       
{
    I2CMSCR = 0x04;     //发送RECV命令
    hardiic_wait();
    return I2CRXD;
}

//========================================================================
// 描述: IIC读取n个字节数据.
// 参数: 设备地址（8位模式，7位地址需要左移一位），寄存器地址，缓存数据地址，数量
// 返回: none.
//========================================================================
void hardiic_read_nbyte(uint8 device_addr, uint8 reg_addr, uint8 *p, uint8 number)
{
    hardiic_start();                        //开始信号
    hardiic_send_byte(device_addr);      //发送器件写地址
    hardiic_wait_ack();
    hardiic_send_byte(reg_addr);                //发送寄存器地址
    hardiic_wait_ack();

    hardiic_start();                        //重复开始信号
    hardiic_send_byte(device_addr | 0x01);      //发送器件读地址
    hardiic_wait_ack();	
    do
    {
        *p = hardiic_read_byte();
        p++;
        if(number != 1) hardiic_ack();     

    }while(--number);
    hardiic_nack(); 
    hardiic_stop();
}

//========================================================================
// 描述: IIC写n个字节数据.
// 参数: 设备地址（8位模式，7位地址需要左移一位），寄存器地址，缓存数据地址，数量
// 返回: none.
//========================================================================
void hardiic_write_nbyte(uint8 device_addr, uint8 reg_addr, uint8 *p, uint8 number)
{
    hardiic_start();                        //开始信号
    hardiic_send_byte(device_addr);      //发送器件写地址
    hardiic_wait_ack();
    hardiic_send_byte(reg_addr);                //发送寄存器地址
    hardiic_wait_ack();
    do
    {
        hardiic_send_byte(*p++);             //发送数据
        hardiic_wait_ack();
    }while(--number);
    hardiic_stop();                          //发送停止命令
}

#endif          //hardiic